package com.suishoupai.xmb.service;

import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.suishoupai.xmb.dao.*;
import com.suishoupai.xmb.entity.*;
import com.suishoupai.xmb.exception.XmbException;
import com.suishoupai.xmb.utils.SecurityUserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by caojian on 2017/4/12.
 */
@Service
public class OrdersService {
    private static Log log = LogFactory.getLog(OrdersService.class);
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private CutGoodsMapper cutGoodsMapper;
    @Autowired
    private GoodsSnapshotMapper goodsSnapshotMapper;
    @Autowired
    private CutOrdersMapper cutOrdersMapper;
    @Autowired
    private CutGoodsSnapshotMapper cutGoodsSnapshotMapper;
    @Autowired
    private CutUserSaleMapper cutUserSaleMapper;
    @Autowired
    private CutXiaoquMapper cutXiaoquMapper;
    @Autowired
    private CutSaleXiaoquMapper cutSaleXiaoquMapper;
    @Autowired
    private CutBlacklistMapper cutBlacklistMapper;
    @Autowired
    private CutUserBuyMapper cutUserBuyMapper;
    @Autowired
    private CutDeliveryDiscountMapper cutDeliveryDiscountMapper;
    @Autowired
    private HuanxinService huanxinService;

    @Value("${order.submit-once-goods-max}")
    private int ORDER_GOODS_ONCE_MAX;

    @Value("${order.no-pay-max}")
    private int noPayOrderNumberMax;
    @Value("${order.close-score}")
    private int orderCloseScore;

    /**
     * 获取用户订单列表
     *
     * @param userId
     * @param status
     * @param ordersId 分页筛选
     * @return
     */
    public List<CutOrders> getOrdersListByUserIdAndStatus(long userId, Integer status, Long ordersId) {
        return cutOrdersMapper.selectCutOrdersListByUserIdAndStatus(userId, status, ordersId);
    }

    /**
     * 获取用户订单列表
     *
     * @param userId
     * @return
     */
    public List<CutOrders> getOrdersListByUserId(long userId) {
        return cutOrdersMapper.selectCutOrdersListByUserIdAndStatus(userId, null, null);
    }

    /**
     * 获取店铺订单列表
     *
     * @param saleId
     * @param status
     * @return
     */
    public List<CutOrders> getOrdersListBySaleIdAndStatus(long saleId, int status) {
        return cutOrdersMapper.selectCutOrdersListBySaleIdAndStatus(saleId, status);
    }

    /**
     * 删除未确认的订单(可能不存在这样的订单)
     */
    @Transactional
    public void deleteNoConfirmOrder(long userId) {
        Orders orders = cutOrdersMapper.selectByUserIdAndStatus(userId, OrderStatusEnum.NO_CONFIRM.getValue());
        if (orders == null) {
            return;
        }
        if (cutOrdersMapper.deleteByPrimaryKey(orders.getId()) == 0) {
            throw new RuntimeException("删除失败！");
        }
        if (cutGoodsSnapshotMapper.deleteByOrdersId(orders.getId()) == 0) {
            throw new RuntimeException("删除失败！");
        }
    }

    /**
     * 创建订单（未确认）
     */
    @Transactional
    public CutOrders orderCreate(List<GoodsSnapshot> goodsSnapshots, long userId) throws XmbException {
        if (goodsSnapshots.size() > ORDER_GOODS_ONCE_MAX) {
            throw XmbException.newError("商品种数达到上限（" + ORDER_GOODS_ONCE_MAX + "）！");
        }
        List<Long> goodsIds = new ArrayList<Long>();
        for (GoodsSnapshot goodsSnapshot : goodsSnapshots) {
            goodsIds.add(goodsSnapshot.getGoodsId());
        }
        List<Goods> goodsList = cutGoodsMapper.selectInPrimaryKey(goodsIds);
        //得到总价和店铺id
        long total = 0;
        long saleId = 0;
        for (Goods goods : goodsList) {
            if (saleId == 0) {
                saleId = goods.getSaleId();
            } else {
                if (saleId != goods.getSaleId()) {
                    throw new RuntimeException("商品所属店铺不同！");
                }
            }
            //计算总价,并制作商品快照
            for (GoodsSnapshot goodsSnapshot : goodsSnapshots) {
                long goodsId = goodsSnapshot.getGoodsId();
                if (goodsId == goods.getId()) {
                    goodsSnapshot.setCreateTime(System.currentTimeMillis());
                    goodsSnapshot.setPrice(goods.getPrice());
                    goodsSnapshot.setName(goods.getName());
                    goodsSnapshot.setImageKey(goods.getImageKey());
                    total += goodsSnapshot.getCount() * goods.getPrice();
                    break;
                }
            }
        }
        CutUserSale cutUserSale = cutUserSaleMapper.selectByPrimaryKey(saleId);
        //得到配送费
        long deliveryPrice = cutUserSale.getUserSale().getDeliveryPrice();
        List<DeliveryDiscount> deliveryDiscounts = cutDeliveryDiscountMapper.selectBySaleId(saleId);
        for (DeliveryDiscount deliveryDiscount : deliveryDiscounts) {
            if (total >= deliveryDiscount.getFull()) {
                if (deliveryPrice > deliveryDiscount.getDeliveryPrice()) {
                    deliveryPrice = deliveryDiscount.getDeliveryPrice();
                }
            }
        }
        //加上配送费
        total += deliveryPrice;
        //开始设置数据并插入数据库
        Orders orders = new Orders();
        orders.setUserId(userId);
        orders.setCreateTime(System.currentTimeMillis());
        orders.setSaleId(saleId);
        orders.setTotal(total);
        orders.setDeliveryPrice(deliveryPrice);
        orders.setStatus(OrderStatusEnum.NO_CONFIRM.getValue());
        if (ordersMapper.insertSelective(orders) == 0) {
            throw new RuntimeException("订单创建失败！");
        }
        for (GoodsSnapshot goodsSnapshot : goodsSnapshots) {
            goodsSnapshot.setOrdersId(orders.getId());
            if (goodsSnapshotMapper.insertSelective(goodsSnapshot) == 0) {
                throw new RuntimeException("订单创建失败！");
            }
        }
        //订单创建成功返回订单快照
        CutOrders cutOrders = new CutOrders();
        cutOrders.setOrders(orders);
        cutOrders.setGoodsSnapshots(goodsSnapshots);
        return cutOrders;
    }

    /**
     * 订单确认
     */
    @Transactional
    public void orderConfirm(Orders orders, long xiaoquId) throws XmbException {
        long ordersId = orders.getId();
        long userId = orders.getUserId();

        //检查非法操作
        Orders temp = cutOrdersMapper.selectByPrimaryKey(ordersId);
        if (temp.getUserId() != userId) {
            throw new RuntimeException("非法操作！");
        }
        Xiaoqu xiaoqu = cutXiaoquMapper.selectByPrimaryKey(xiaoquId);
        if (cutSaleXiaoquMapper.selectCountByPrimaryKey(xiaoquId, temp.getSaleId()) == 0) {
            throw XmbException.newError("该小区已不在店铺服务范围内。");
        }
        //检查重复操作
        if (temp.getStatus() == OrderStatusEnum.WAIT_PAY.getValue()) {
            throw XmbException.newRepeatRequest();
        }
        //检查用户
        UserBuy userBuy = cutUserBuyMapper.selectByPrimaryKey(userId);
        if (userBuy.getNoPayOrders() >= noPayOrderNumberMax) {
            throw XmbException.newError("有待支付的订单尚未处理。");
        }
        //检查店铺
        CutUserSale cutUserSale = cutUserSaleMapper.selectByPrimaryKey(temp.getSaleId());
        if (cutUserSale.getUserSale().getStatus() == SaleStatusEnum.REST.getValue()) {
            throw XmbException.newError("该店铺处于休息中。");
        }
        if (cutBlacklistMapper.selectByPrimaryKey(temp.getSaleId()) != null) {
            throw XmbException.newError("该店铺已被系统冻结。");
        }
        //检查商品数量是否够
        List<GoodsSnapshot> goodsSnapshots = cutGoodsSnapshotMapper.selectByOrdersId(ordersId);
        List<Long> goodsIds = new ArrayList<Long>();
        for (GoodsSnapshot goodsSnapshot : goodsSnapshots) {
            goodsIds.add(goodsSnapshot.getGoodsId());
        }
        List<Goods> goodsList = cutGoodsMapper.selectInPrimaryKey(goodsIds);
        for (Goods goods : goodsList) {
            for (GoodsSnapshot goodsSnapshot : goodsSnapshots) {
                if (goodsSnapshot.getGoodsId() == goods.getId()) {
                    if (goods.getStatus() == GoodsStatusEnum.OFF_SHELVES.getValue()) {
                        throw XmbException.newError("商品（" + goods.getName() + "）已下架。");
                    }
                    if (goodsSnapshot.getCount() > goods.getNumber()) {
                        throw XmbException.newError("商品（" + goods.getName() + "）剩余数量：" + goods.getNumber() + "，已不足" + goodsSnapshot.getCount() + "。");
                    }
                    break;
                }
            }
        }

        String contact = orders.getContact();
        String address = orders.getAddress();
        int type = orders.getType();
        String note = orders.getNote();
        //更新订单
        Orders updateOrders = new Orders();
        updateOrders.setId(ordersId);
        updateOrders.setContact(contact);
        updateOrders.setAddress(xiaoqu.getName() + address);
        updateOrders.setType(type);
        updateOrders.setNote(note);
        if (type == OrderTypeEnum.PAY_ON_DELIVERY.getValue()) {
            updateOrders.setStatus(OrderStatusEnum.WAIT_SEND.getValue());
        } else if (type == OrderTypeEnum.ONLINE_PAYMENT.getValue()) {
//            updateOrders.setStatus(OrderStatusEnum.WAIT_PAY.getValue());
            throw XmbException.newError("暂不支持在线支付。");
        }
        updateOrders.setCreateTime(System.currentTimeMillis());
        if (cutOrdersMapper.updateByPrimaryKeyWhenStatus(updateOrders, OrderStatusEnum.NO_CONFIRM.getValue()) == 0) {
            throw new RuntimeException("更新失败！");
        }
        //减少商品数量
        for (GoodsSnapshot goodsSnapshot : goodsSnapshots) {
            if (cutGoodsMapper.reduceNumber(goodsSnapshot.getGoodsId(), goodsSnapshot.getCount()) == 0) {
                throw new RuntimeException("更新失败！");
            }
        }
        if (type == OrderTypeEnum.ONLINE_PAYMENT.getValue()) {
            //添加未付订单
            if (cutUserBuyMapper.addNoPayByPrimaryKey(userId, noPayOrderNumberMax) == 0) {
                throw new RuntimeException("更新失败！");
            }
        }
        try {
            huanxinService.sendMessage(cutUserSale.getUser().getId() + "", HuanxinMessage.newMessage(HuanxinMessage.ORDER_NEW_TYPE, "有新订单！").toJSONString());
        } catch (XmbException e) {
            log.error("发送环信消息失败---" + e.getMessage());
        }
    }

    /**
     * 关闭未付订单
     */
    @Transactional
    public void closeNoPayOrder(long ordersId, String description, long userId) throws XmbException {
        //检查
        Orders temp = cutOrdersMapper.selectByPrimaryKey(ordersId);
        if (temp.getUserId() != userId) {
            throw new RuntimeException("非法操作！");
        }
        if (temp.getStatus() == OrderStatusEnum.CLOSE.getValue()) {
            throw XmbException.newRepeatRequest();
        }
        //更新订单
        Orders orders = new Orders();
        orders.setId(ordersId);
        orders.setDescription(description);
        orders.setStatus(OrderStatusEnum.CLOSE.getValue());
        if (cutOrdersMapper.updateByPrimaryKeyWhenStatus(orders, OrderStatusEnum.WAIT_PAY.getValue()) == 0) {
            throw new RuntimeException("更新失败！");
        }
        //释放库存
        List<GoodsSnapshot> goodsSnapshotList = cutGoodsSnapshotMapper.selectByOrdersId(ordersId);
        for (GoodsSnapshot goodsSnapshot : goodsSnapshotList) {
            long goodsId = goodsSnapshot.getGoodsId();
            //释放库存
            if (cutGoodsMapper.addNumber(goodsId, goodsSnapshot.getCount()) == 0) {
                throw XmbException.newError("更新goods失败" + goodsId);
            }
        }
        //减少用户评分
        if (cutUserBuyMapper.orderCloseByPrimaryKey(userId, orderCloseScore) == 0) {
            throw XmbException.newError("更新UserBuy失败" + userId);
        }
    }

    /**
     * 订单完成
     */
    @Transactional
    public void orderComplete(long ordersId, long saleId) throws XmbException {
        //检查
        Orders temp = cutOrdersMapper.selectByPrimaryKey(ordersId);
        if (temp.getSaleId() != saleId) {
            throw new RuntimeException("非法操作！");
        }
        if (temp.getStatus() == OrderStatusEnum.COMPLETE.getValue()) {
            throw XmbException.newRepeatRequest();
        }
        //操作
        Orders orders = new Orders();
        orders.setId(ordersId);
        orders.setStatus(OrderStatusEnum.COMPLETE.getValue());
        if (cutOrdersMapper.updateByPrimaryKeyWhenStatus(orders, OrderStatusEnum.WAIT_SEND.getValue()) == 0) {
            throw new RuntimeException("更新失败！");
        }
        //增加店铺销售量
        if (cutUserSaleMapper.addSalesVolume(saleId) == 0) {
            throw new RuntimeException("更新失败！");
        }
        //增加商品销售量
        List<GoodsSnapshot> goodsSnapshots = cutGoodsSnapshotMapper.selectByOrdersId(ordersId);
        for (GoodsSnapshot goodsSnapshot : goodsSnapshots) {
            if (cutGoodsMapper.addSalesVolume(goodsSnapshot.getGoodsId(), goodsSnapshot.getCount()) == 0) {
                throw new RuntimeException("更新失败！");
            }
        }
    }
}
